package com.wk.myplayer.opengl;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.view.Surface;
import com.demo.myplayer.R;
import com.wk.myplayer.util.WlShaderUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class WlRender implements GLSurfaceView.Renderer {
    private Context context;
    private SurfaceTexture surfaceTexture;
    private OnSurfaceCreateListener onSurfaceCreateListener;
    private OnRenderListener onRenderListener;

    WlRender(Context context) {
        this.context = context;
    }


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        initRenderMediacodec();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height); // 确定绘制区域
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // 清空
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        surfaceTexture.updateTexImage(); //更新内容
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); // 图形绘制
    }



    private void initRenderMediacodec() {
        // 图象从纹理图象空间映射到帧缓冲图象空间  相关配置
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        String vertexSource = WlShaderUtil.readRawTxt(context, R.raw.vertex_shader); // 获取glsl 代码
        String fragmentSource = WlShaderUtil.readRawTxt(context, R.raw.fragment_mediacodec);
        int program_mediacodec = WlShaderUtil.createProgram(vertexSource, fragmentSource);
        GLES20.glUseProgram(program_mediacodec);// 将程序加入到OpenGLES环境

        int avPosition_mediacodec = GLES20.glGetAttribLocation(program_mediacodec, "av_Position"); // 顶点坐标
        GLES20.glEnableVertexAttribArray(avPosition_mediacodec);  // 启用坐标数组
        GLES20.glVertexAttribPointer(avPosition_mediacodec, 2, GLES20.GL_FLOAT, false, 8, getVertexFloatBuffer());  // 准备位置数据
        int afPosition_mediacodec = GLES20.glGetAttribLocation(program_mediacodec, "af_Position"); // 纹理坐标 ,根据name获取attribute类型变量的id
        GLES20.glEnableVertexAttribArray(afPosition_mediacodec); // 启用坐标数组
        GLES20.glVertexAttribPointer(afPosition_mediacodec, 2, GLES20.GL_FLOAT, false, 8, getTextureFloatBuffer()); // 准备位置数据


        GLES20.glActiveTexture(GLES20.GL_TEXTURE0); // 选择活动纹理单元

        int[] textureids = new int[1];
        GLES20.glGenTextures(1, textureids, 0); // 生成纹理，并返回纹理id
        int  textureId_mediacodec = textureids[0];
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId_mediacodec);// 绑定纹理

        int samplerOES_mediacodec = GLES20.glGetUniformLocation(program_mediacodec, "sTexture"); // 纹理类型,根据name获取uniform类型变量的id
        GLES20.glUniform1i(samplerOES_mediacodec, 0); // 设置纹理采样器 ， 纹理第n层


        // 上面所有的 OpenGL 配置，都是为了生成 SurfaceTexture ？ ， 如果可以用SurfaceTexture做数据二次开发，最后通过
        // surface显示出来。  如果不用做特效，是不是就不用通过SurfaceTexture了，自然OpenGL也不用了。 ？？
        surfaceTexture = new SurfaceTexture(textureId_mediacodec);
        surfaceTexture.setOnFrameAvailableListener(onFrameAvailableListener);
        Surface surface = new Surface(surfaceTexture);
        if(onSurfaceCreateListener != null) {
            // 传给player，用来 mediaCodec.configure(mediaFormat, surface, null, 0);
            onSurfaceCreateListener.onSurfaceCreate(surface);
        }
    }

    private SurfaceTexture.OnFrameAvailableListener onFrameAvailableListener =  new SurfaceTexture.OnFrameAvailableListener() {
        @Override
        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            if(onRenderListener != null)  {
                onRenderListener.onFrameAvailable();
            }
        }
    };

    private FloatBuffer getVertexFloatBuffer(){
        float[] vertexData ={
                -1f, -1f, // 左下角
                1f, -1f, // 右下角
                -1f, 1f, // 左上角
                1f, 1f // 右上角
        };
        FloatBuffer vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4) // 每个元素占4个byte
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
                .put(vertexData);
        vertexBuffer.position(0);
        return  vertexBuffer ;
    };


    private FloatBuffer getTextureFloatBuffer(){
        float[] textureData ={
                0f,1f,
                1f, 1f,
                0f, 0f,
                1f, 0f
        };
        FloatBuffer textureBuffer = ByteBuffer.allocateDirect(textureData.length * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
                .put(textureData);
        textureBuffer.position(0);

        return  textureBuffer ;
    };


    public void setOnSurfaceCreateListener(OnSurfaceCreateListener onSurfaceCreateListener) {
        this.onSurfaceCreateListener = onSurfaceCreateListener;
    }

    void setOnRenderListener(OnRenderListener onRenderListener) {
        this.onRenderListener = onRenderListener;
    }

    public interface OnSurfaceCreateListener  {
        void onSurfaceCreate(Surface surface);
    }

    public interface OnRenderListener{
        void onFrameAvailable();
    }


}
